package com.zsk.shop.service;


import com.zsk.shop.common.base.BaseResponse;
import com.zsk.shop.common.utils.DateUtils;
import com.zsk.shop.common.utils.ImageRead;
import com.zsk.shop.common.utils.ImageVerificationUtil;
import com.zsk.shop.controller.app.CaptchaController;
import com.zsk.shop.entity.VerificationImage;
import com.zsk.shop.exception.ServiceException;
import com.zsk.shop.exception.code.ServiceExceptionCode;
import com.zsk.shop.model.vo.ImageVerificationVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.core.io.Resource;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.Random;

/**
 * @Description: 验证码业务实现类
 * -------------------
 * @Author: Ys
 * @Date: 2022/02/24 17:16
 */

@Service
public class CaptchaServiceImpl {

    @javax.annotation.Resource
    private VerificationImageService verificationImageService;

    /**
     * 日志
     */
    private static final Logger log = LoggerFactory.getLogger(CaptchaController.class);

    /**
     * 源图路径前缀
     */
    @Value("${captcha.slide-verification-code.path.origin-image:classpath:static/targets}")
    private String verificationImagePathPrefix;

    /**
     * 模板图路径前缀
     */
    @Value("${captcha.slide-verification-code.path.template-image:classpath:static/templates}")
    private String templateImagePathPrefix;


    /**
     * 获取request对象
     *
     * @return 返回request对象
     */
    protected static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 获取response对象
     *
     * @return 返回response对象
     */
    protected static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    /**
     * 获取滑动验证码
     *
     * @return 滑动验证码
     * @throws ServiceException 获取滑动验证码异常
     */
    public BaseResponse<ImageVerificationVo> selectSlideVerificationCode() throws ServiceException {

        ImageVerificationVo imageVerificationVo = null;
        try {
            //  随机取得原图文件夹中一张图片
            ImageRead originImageRead = readTargetImage();
            //  获取模板图片文件
            ImageRead templateImageRead = readTemplateImage(templateImagePathPrefix.concat("/template.png"));
            //  获取描边图片文件
            ImageRead borderImageRead = readBorderImageFile(templateImagePathPrefix.concat("/border.png"));
            //  获取原图文件类型
            String originImageFileType = originImageRead.getFileExtension();
            //  获取模板图文件类型
            String templateImageFileType = templateImageRead.getFileExtension();
            //  获取边框图文件类型
            String borderImageFileType = borderImageRead.getFileExtension();
            //  读取原图
            BufferedImage verificationImage = originImageRead.getImage();
            //  读取模板图
            BufferedImage readTemplateImage = templateImageRead.getImage();
            //  读取描边图片
            BufferedImage borderImage = borderImageRead.getImage();

            //  获取原图感兴趣区域坐标
            imageVerificationVo = ImageVerificationUtil.generateCutoutCoordinates(verificationImage, readTemplateImage);
            VerificationImage image = new VerificationImage();
            image.setContent(imageVerificationVo.getX()+"");
            image.setResult(imageVerificationVo.getX()+"");
            image.setInvalidTime(DateUtils.addMinute(1));

            int y = imageVerificationVo.getY();
            int x = imageVerificationVo.getX();
            //  根据原图生成遮罩图和切块图
            imageVerificationVo = ImageVerificationUtil.pictureTemplateCutout(verificationImage, originImageRead.getInputStream(), originImageFileType, readTemplateImage, templateImageFileType, imageVerificationVo.getX(), imageVerificationVo.getY());
            //   剪切图描边
            imageVerificationVo = ImageVerificationUtil.cutoutImageEdge(imageVerificationVo, borderImage, borderImageFileType);
            imageVerificationVo.setY(y);
            verificationImageService.getBaseMapper().insertSelective(image);
            imageVerificationVo.setId(image.getId());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return BaseResponse.error("服务器异常");
        }

        return BaseResponse.success(imageVerificationVo);
    }

    /**
     * 读取目标图
     *
     * @return
     * @throws ServiceException
     */
    public ImageRead readTargetImage() throws ServiceException {
        ImageRead imageRead = null;

        try {
            Random random = new Random(System.currentTimeMillis());
            if (verificationImagePathPrefix.indexOf("classpath") >= 0) {
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                Resource[] resources = resolver.getResources(verificationImagePathPrefix.concat("/*"));

                if (resources == null) {
                    throw new RuntimeException("not found target image");
                }
                int i = random.nextInt(resources.length);
                imageRead = new ImageRead();
                imageRead.setImage(ImageIO.read(resources[i].getInputStream()));
                String extension = resources[i].getFilename().substring(resources[i].getFilename().lastIndexOf(".") + 1);
                imageRead.setInputStream(resources[i].getInputStream());
                imageRead.setFileExtension(extension);
            } else {
                File importImage = new File(verificationImagePathPrefix);
                if (importImage == null) {
                    throw new RuntimeException("not found target image");
                }
                File[] files = importImage.listFiles();
                int i = random.nextInt(files.length);
                imageRead = new ImageRead();
                imageRead.setImage(ImageIO.read(files[i]));
                String extension = files[i].getName().substring(files[i].getName().lastIndexOf(".") + 1);
                imageRead.setFileExtension(extension);
                imageRead.setInputStream(new FileInputStream(files[i]));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(ServiceExceptionCode.IO_EXCEPTION);
        }
        return imageRead;
    }

    /**
     * 读取模板图
     * @param path
     * @return
     * @throws ServiceException
     */
    public ImageRead readTemplateImage(String path) throws ServiceException {
        ImageRead templateImageFile = null;
        try {
            if (templateImageFile != null) {
                return templateImageFile;
            }
            templateImageFile = new ImageRead();
            if (verificationImagePathPrefix.indexOf("classpath") >= 0) {
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                Resource resource = resolver.getResource(path);
                if (resource == null) {
                    throw new RuntimeException("not found template image");
                }
                templateImageFile.setImage(ImageIO.read(resource.getInputStream()));
                String extension = resource.getFilename().substring(resource.getFilename().lastIndexOf(".") + 1);
                templateImageFile.setInputStream(resource.getInputStream());
                templateImageFile.setFileExtension(extension);
            } else {
                File file = new File(path);
                templateImageFile.setImage(ImageIO.read(file));
                String extension = file.getName().substring(file.getName().lastIndexOf(".") + 1);
                templateImageFile.setInputStream(new FileInputStream(file));
                templateImageFile.setFileExtension(extension);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(ServiceExceptionCode.IO_EXCEPTION);
        }
        return templateImageFile;
    }

    /**
     * 读取边框图
     *
     * @param path
     * @return
     * @throws ServiceException
     */
    public ImageRead readBorderImageFile(String path) throws ServiceException {
        ImageRead borderImageFile = null;
        try {
            if (borderImageFile != null) {
                return borderImageFile;
            }
            borderImageFile = new ImageRead();
            if (templateImagePathPrefix.indexOf("classpath") >= 0) {
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                Resource resource = resolver.getResource(path);
                if (resource == null) {
                    throw new RuntimeException("not found template image");
                }
                borderImageFile.setImage(ImageIO.read(resource.getInputStream()));
                String extension = resource.getFilename().substring(resource.getFilename().lastIndexOf(".") + 1);
                borderImageFile.setInputStream(resource.getInputStream());
                borderImageFile.setFileExtension(extension);
            } else {
                File file = new File(path);
                borderImageFile.setImage(ImageIO.read(file));
                String extension = file.getName().substring(file.getName().lastIndexOf(".") + 1);
                borderImageFile.setInputStream(new FileInputStream(file));
                borderImageFile.setFileExtension(extension);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException(ServiceExceptionCode.IO_EXCEPTION);
        }
        return borderImageFile;
    }

//    /**
//     * 滑动验证码验证方法
//     *
//     * @param x x轴坐标
//     * @param y y轴坐标
//     * @return 滑动验证码验证状态
//     * @throws ServiceException 验证滑动验证码异常
//     */
//    public boolean checkVerificationResult(String x, String y) throws ServiceException {
//        int threshold = 5;
//        try {
//            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//            ImageVerificationVo imageVerificationVo = (ImageVerificationVo) request.getSession().getAttribute("imageVerificationVo");
//            if (imageVerificationVo != null) {
//                if ((Math.abs(Integer.parseInt(x) - imageVerificationVo.getX()) <= threshold) && y.equals(String.valueOf(imageVerificationVo.getY()))) {
//                    System.out.println("验证成功");
//                    return true;
//                } else {
//                    System.out.println("验证失败");
//                    return false;
//                }
//            } else {
//                return false;
//            }
//        } catch (Exception e) {
//            log.error(e.getMessage(), e);
//            throw new ServiceException(ServiceExceptionCode.IO_EXCEPTION);
//        }
//    }


}